package com.atldy.commerce.filter;

import cn.hutool.core.util.StrUtil;
import com.atldy.commerce.JWTUtils;
import com.atldy.commerce.enums.CommonConstant;
import com.atldy.commerce.vo.LoginUserinfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @version 1.0
 * @Author: lidongyang
 * @CreateTime: 2021-08-11 22:19
 * @Description： 拦截器，用户信息拦截
 */
@Slf4j
@Component
public class LoginUserinfoInterceptor implements HandlerInterceptor {

    /**
     * 前置拦截
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 部分请求不需要带有身份信息, 即白名单
        if (checkWhiteListUrl(request.getRequestURI())) {
            return true;
        }

        //从请求头中获取token
        String token = request.getHeader(CommonConstant.JWT_TOKEN_USER_INFO);
        if (StrUtil.isBlank(token)) {
            throw new RuntimeException("请求未携带token");
        }
        //解析token
        LoginUserinfo loginUserinfo = null;
        try {
            loginUserinfo = JWTUtils.parsingToken(token);
        } catch (Exception e) {
            log.info("解析token失败,失败信息是：[{}]", e.getMessage(), e);
        }

        //判断是否解析token
        if (loginUserinfo == null) {
            log.error("从token获取用户信息失败");
        }
        //把用户信息存入ThreadLocal中
        AccessContent.setLoginUserinfo(loginUserinfo);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 最后通知
     * 一般是进行释放资源操作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (AccessContent.getLoginUserinfo() != null) {
            AccessContent.removeLoginUser();
        }
    }

    /**
     * <h2>校验是否是白名单接口</h2>
     * swagger2 接口
     */
    private boolean checkWhiteListUrl(String url) {

        return StringUtils.containsAny(
                url,
                "springfox", "swagger", "v2",
                "webjars", "doc.html"
        );
    }

}